package com.zyfdroid.backupftpserver.ftplets;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.util.Log;

import com.zyfdroid.backupftpserver.LastModifiedStorageHelper;
import com.zyfdroid.backupftpserver.SAFHelper;
import org.apache.ftpserver.ftplet.FileSystemView;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.FtpFile;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.regex.Pattern;

public class MyFileSystemView implements FileSystemView {
    PackageManager pm;
    Context ctx;
    SAFFileSystemManager safFileSystemManager;
    public MyFileSystemView(PackageManager pm, Context ctx) {
        this.pm = pm;
        this.ctx = ctx;
        safFileSystemManager = new SAFFileSystemManager(ctx);
        try {
            pwd=getHomeDirectory();
        } catch (FtpException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public FtpFile getHomeDirectory() throws FtpException {
        return new RootFtpFile(pm,ctx,safFileSystemManager);
    }


    FtpFile pwd;

    @Override
    public FtpFile getWorkingDirectory() throws FtpException {
        return pwd;
    }

    @Override
    public boolean changeWorkingDirectory(String s) throws FtpException {
        pwd = getByAbsolutePath(normalizePath(s));
        return true;
    }

    private String normalizePath(String relative){
        if(relative.equals("/")){return "/";}
        if(relative.equals(".")){return pwd.getAbsolutePath();}
        if(relative.equals("./")){return pwd.getAbsolutePath();}
        String[] args = relative.split(Pattern.quote("/"));
        ArrayList<String> token = new ArrayList<>();
        if(relative.startsWith("/")){
            token.clear();
        }
        else{
            String[] temp = pwd.getAbsolutePath().split(Pattern.quote("/"));
            Log.e("temp.length",""+temp.length+" -> "+ Arrays.toString(temp));
            for (int i = 0; i < temp.length; i++) {
                if(temp[i].isEmpty()){continue;}
                token.add(temp[i]);
            }


        }
        for (int i = 0; i < args.length; i++) {
            if(args[i].equals("")){
                continue;
            }
            if(args[i].equals(".")){
                continue;
            }
            if(args[i].equals("..")){
                if(token.size()>0){token.remove(token.size()-1);}
                continue;
            }
            token.add(args[i]);
        }
        StringBuilder sb = new StringBuilder();
        for (String s1 : token) {
            sb.append("/").append(s1);
        }
        if(sb.length()==0){sb.append("/");}
        return sb.toString();
    }

    private FtpFile getByAbsolutePath(String abspath) throws FtpException{
        if(abspath.equals("/")){
            return getHomeDirectory();
        }
        if(abspath.equals("/app")){
            return new AppContainerFtpFile(pm);
        }
        if(abspath.startsWith("/app/")){
            try {
                String[] filenames = abspath.split(Pattern.quote("/"));
                String filename = filenames[filenames.length-1];
                AppPackageFtpFile apk = AppContainerFtpFile.getNamePackageMapping(pm).get(filename);
                if(apk!=null){
                    return apk;
                }

                throw new FtpException("No such file or dictionary: "+abspath);
            } catch (Exception e) {
                throw new FtpException("No such file or dictionary: "+abspath);
            }
        }
        if(abspath.equals("/sdcard")){
            return new SdcardRootFtpFile();
        }
        if(abspath.startsWith("/sdcard/")){
            return new SdcardFtpFile(Environment.getExternalStorageDirectory(),abspath.substring(7));
        }
        if(abspath.equals("/extra")){
            return safFileSystemManager;
        }
        if(abspath.startsWith("/extra/")){
            String[] pathParts = abspath.substring("/extra/".length()).split(Pattern.quote("/"));
            if(pathParts.length == 0){
                return safFileSystemManager;
            }
            else{
                try {
                    return safFileSystemManager.getByPath(abspath);
                } catch (FileNotFoundException e) {
                    throw new FtpException("Cannot find saf directory: "  + abspath);
                }
            }
        }

        throw new FtpException("No such file or dictionary: "  + abspath);
    }

    @Override
    public FtpFile getFile(String s) throws FtpException {
        return getByAbsolutePath(normalizePath(s));
    }

    @Override
    public boolean isRandomAccessible() throws FtpException {
        return false;
    }

    @Override
    public void dispose() {
        AppContainerFtpFile.disposeFiles();
        safFileSystemManager.close();
    }
}
